#pragma once

//WGLENGINE_DLL
#ifdef WGLENGINE_DLL
#define WGLENGINE_EXPORT __declspec(dllexport)
#else
#define WGLENGINE_EXPORT __declspec(dllimport)
#endif

#include <SFML\Window.hpp>
#include <SFML\System.hpp>

#include "Settings.h"
#include "AssimpParser.h"
#include <queue>
#include <iostream>
#include <string>
#include <fstream>

#include "assimp/Importer.hpp"	//OO version Header!
#include "assimp/postprocess.h"
#include "assimp/scene.h"
#include "assimp/DefaultLogger.hpp"
#include "assimp/LogStream.hpp"

class WGLENGINE_EXPORT WLoadItem
{
public:
	WLoadItem(std::string fPath)
	{
		this->fPath = fPath;
	}

	~WLoadItem()
	{

	}

	std::string GetPath()
	{
		return fPath;
	}

private:
	std::string fPath;
};

class WGLENGINE_EXPORT WContext
{
public:
	WContext()
	{
		created = false;
	}
	WContext(bool& running)
	{
		created = false;
		this->running = running;
	}
	~WContext(){}

	bool ContextCreated()
	{
		return created;
	}

	
	void AddWLoadItem(std::shared_ptr<WLoadItem> item)
	{
		loadingQueue.push(item);
	}


	virtual void Run() = 0;

protected:
	
	//check if file exists and can be opened
	bool CheckFile(const std::string& pFile)
	{
		std::ifstream fin(pFile);
		if(!fin.fail())
		{
			fin.close();
			return true;
		}
		else
		{
			std::cout<< ("Couldn't open file: " ) << pFile << std::endl;
			return false;
		}
	}
	
	//load a 3d model
	bool Import3DFromFile(const std::string& pFile)
	{
		bool success = CheckFile(pFile);
		if(success)
		{
			const aiScene* scene = importer.ReadFile( pFile, aiProcess_GenSmoothNormals | 
																aiProcess_Triangulate);
			if(!scene)
			{
				std::cout<< (importer.GetErrorString()) << std::endl;
				return false;
			}

			AssimpParser p(scene, pFile);
			p.Parse();
			return true;
		}
		return false;
	}

	//load a 3d model, and return an additional importedNode
	bool Import3DFromFile(const std::string& pFile, std::shared_ptr<SceneNode>& importedNode)
	{
		bool success = CheckFile(pFile);
		if(success)
		{
			const aiScene* scene = importer.ReadFile( pFile, aiProcess_GenSmoothNormals | 
																aiProcess_Triangulate);
			if(!scene)
			{
				std::cout<< (importer.GetErrorString()) << std::endl;
				return false;
			}

			AssimpParser p(scene, pFile);
			importedNode = p.Parse();
			return true;
		}
		return false;
	}

	virtual void CreateContext() = 0;
	
	Assimp::Importer importer;
	std::queue<std::shared_ptr<WLoadItem>> loadingQueue;
	bool running;
	bool created;
};